WebSocket 是 HTML5 開始提供的一種瀏覽器與伺服器間進行全雙工通訊的網路技術。 在 WebSocket API 中,瀏覽器和伺服器只需要要做一個握手的動作,然後,瀏覽器和伺服器之間就形成了一條快速通道。兩者之間就直接可以資料互相傳送。
簡單來說,就是有 Client & Server 兩端透過 WebSocket 互相傳遞與接收資料,並且即時顯示在頁面上。
<!DOCTYPE html>
<meta charset="utf-8" />
<title>WebSocket Test</title>
<script language="javascript" type="text/javascript">
var wsUri = "ws://echo.websocket.org/";
var output;
function init() {
output = document.getElementById("output");
testWebSocket();
}
function testWebSocket() {
websocket = new WebSocket(wsUri);
websocket.onopen = function(evt) {
onOpen(evt)
};
websocket.onclose = function(evt) {
onClose(evt)
};
websocket.onmessage = function(evt) {
onMessage(evt)
};
websocket.onerror = function(evt) {
onError(evt)
};
}
function onOpen(evt) {
writeToScreen("CONNECTED");
doSend("WebSocket rocks");
}
function onClose(evt) {
writeToScreen("DISCONNECTED");
}
function onMessage(evt) {
writeToScreen('RESPONSE: ' + evt.data+'');
websocket.close();
}
function onError(evt) {
writeToScreen('ERROR: ' + evt.data);
}
function doSend(message) {
writeToScreen("SENT: " + message);
websocket.send(message);
}
function writeToScreen(message) {
var pre = document.createElement("p"); pre.style.wordWrap = "break-word"; pre.innerHTML = message; output.appendChild(pre);
}
window.addEventListener("load", init, false);
</script>
<h2>WebSocket Test</h2>
<div id="output"></div>
WebSocket 已經建立好許多 function ,我們可以直接用他的 function,當然也不一定要全部 function 都用到,或是可以做點小修改,像我主管給我的範本就跟官網提供的有一點點不一樣(但基本上的呼叫是大同小異的)
var wsUri = "ws://echo.websocket.org/";
,因為如果一開始沒有把傳輸的網址寫正確,之後的效果根本也跑不出來。記得要把 http://
改成 ws://
。websocket.onopen
這個事件是用來判斷前面的 wsUri
是否有順利抓到,如果有抓到表示 onopen,可以利用console.log
或是alert
做個標記:console.log("連線成功");
websocket.onclose
是用來表示當連線中斷時,會出現什麼訊息或事件。wescoket.onmessage
是整個 WebSocket 的重頭戲,連線後,我們就可以在onmessage
裏面寫上任何想要傳輸的事件內容。wescoket.onmessage
,wescoket.onerror
是用來判斷連線或事件的正確與否,如果有出現了任何錯誤,就會觸發onerror
事件,所以我們可以在這邊進行除錯。WebSocket 主要就是這四個事件,所以其實不難。那要怎麼利用 jQuery 結合 WebSocket 做出想要的功能呢?我們做法通常是將 jQuery 的主要 function 跟 WebSocket 拆開來,簡單架構參考如下:
主資料夾
├ effect.js
├ websocket.client.js
├ websocket.master.js
├ websocket.client.html
├ websocket.master.html
由此可看出,將主要的功能寫在 effect.js 裏頭, client.js(html) 與 master.js(html) 分別用來表示兩個不同網頁,他們可以有不同的功能,也可以互相傳收資料 。
在 effect.js 先將所有要顯示的資料存到變數中:
var _name = $("#name").val();
var _company = $("#company").val();
利用 JSON 將資料送給 WebSocket:
websocket.send(JSON.stringify({
'username': _name,
'company': _company,
}));
在 client.js 將收到的資料存到變數中並調用:(請寫在websocket.onmessage
事件裡。)
//設置一個變數 data, 將剛剛 JSON 的資料存入
var data = $.parseJSON(e.data);
//以下可調用該 data
username = data.username
company = data.company
以上簡單幾行,就可以完成 WebSocket 的基本功能囉 🙂
假使我們希望在 master.html 做了一個動作 (比如說點選特定的分頁時),client.html 就會秀出一個 DIV。那麼要怎麼做出這功能呢?
我們在切換 TAB 的時候,通常網址列後面都會多一個「#+英數字」作為標記,而我們可以利用這個標記來識別現在是切換到第幾個分頁,然後針對指定的分頁,在 client.html 顯示一個 DIV。
先在 master.js 設定一個事件,將 #(hash) 給擷取出來:
$(window).keyup('hashchange', function() {
var tab= location.hash;
console.log(location.hash);
websocket.send(JSON.stringify({'tab' : tab}));
});
我有用console.log
記錄每一次的 hash 變化,確定他有抓到 hash,然後用websocket.send
寫到 JSON
ps. 這個 keyup 事件不一定要寫在websocket.onmessage
裡。
同樣在 client.js 將資料抓出來,然後做判斷:
//如果 data.tab 有資料
if (data.tab) {
//因為 data.tab 抓到的資料是 #1, #2, #3... 這樣的值,為了只取數字,所以用 substring 去做截斷
for(var x = 1; x < data.tab.substring(1,2); x ++) {
if(x == 1){
$("div").css("display", "block");
}
};
};
利用這樣的概念與方法,就可以簡單地在兩端互傳資料囉
Super Sync Sports 是個利用 WebSocket 做的運動小遊戲,請先用 web 端瀏覽該網站,然後他會要你也用手機開啟這個網站,將 web 跟手機連線之後,就可以利用手機控制 web 介面來跑步、游泳,或是騎腳踏車。
而且還可以多人連線喔,超酷